package org.wzy.design.patterns.proxy.cglib;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
 * ClassName: GPMeipo <br/>
 * Function: TODO ADD FUNCTION. <br/>
 * Reason: TODO ADD REASON(可选). <br/>
 * date: 2017年6月15日 下午5:29:15 <br/>
 * 
 * @author wzy_h
 * @version
 * @since JDK 1.8
 */
public class GPMeipo implements MethodInterceptor {

	// 疑问？
	// 好像并没有持有被代理对象的引用
	public Object getInstance(Class<?> clz) throws Exception {
		Enhancer enhancer = new Enhancer();
		// 把父类设置为谁？
		// 这一步就是告诉cglib生成的子类需要继承哪个类
		enhancer.setSuperclass(clz);

		// 设置回调intercept()方法
		enhancer.setCallback(this);

		/**
		 * 1. 生成源代码 2. 编译成class文件 3. 加载到JVM中，并返回被代理对象
		 */
		return enhancer.create();
	}

	/**
	 * 同样是做了字节码重组这件事 对于使用API的用户来说，是无感知的
	 */
	@Override
	public Object intercept(Object obj, Method method, Object[] arg2, MethodProxy proxy) throws Throwable {
		System.out.println("我是媒婆，得给你找个异性！");
		System.out.println("开始进行海选......");
		System.out.println("-------------------------------");

		// 这个obj的引用是由CGlib给我们new出来的
		// cglib new出來以後的對象，是被代理對象的子類(繼承了我們自己寫的那個類)
		// OOP 在new子类之前，实际上默认先调用了我们super()方法的，new了子类的同时也必须先new出父类，相当于间接持有了父类的引用
		// 子类重写了父类所有的方法
		// 我们改变子类对象的某些属性是可以间接地操作父类的属性的
		
		/**
		 * 特别注意：如果用的是invoke可能回导致死循环，因为相当于在子类中递归调用了findLover()方法
		 */
		proxy.invokeSuper(obj, arg2);

		System.out.println("-------------------------------");
		System.out.println("如果合适的话，就准备办事儿！");

		return null;
	}

}
